import { IRippleOptions } from '../ripple-types'
import { createContainer, createRippleElement, getToFurthestCorner } from './useCreateElement'
import { decrementRippleCount, deleteRippleCount, getRippleCount, incrementRippleCount } from './useRippleCount'

const MULTIPLE_NUMBER = 2.05
export default function (event: PointerEvent, el: HTMLElement, options: IRippleOptions) {
  const rect = el.getBoundingClientRect()
  const computedStyles = window.getComputedStyle(el)
  const x = event.x - rect.left
  const y = event.y - rect.top
  const size = MULTIPLE_NUMBER * getToFurthestCorner(x, y, rect)
  const rippleContainer = createContainer(computedStyles)
  const rippleEl = createRippleElement(x, y, size, options)
  let originalPositionValue = ''
  let shouldDissolveRipple = false
  let token: number | undefined = undefined
  function dissolveRipple() {
    rippleEl.style.transition = 'opacity 150ms linear'
    rippleEl.style.opacity = '0'

    setTimeout(() => {
      rippleContainer.remove()

      decrementRippleCount(el)

      if (getRippleCount(el) === 0) {
        deleteRippleCount(el)
        el.style.position = originalPositionValue
      }
    }, 150)
  }
  function releaseRipple(e?: PointerEvent) {
    if (typeof e !== 'undefined') {
      document.removeEventListener('pointerup', releaseRipple)
      document.removeEventListener('pointercancel', releaseRipple)
    }

    if (shouldDissolveRipple) {
      dissolveRipple()
    } else {
      shouldDissolveRipple = true
    }
  }

  function cancelRipple() {
    clearTimeout(token)

    rippleContainer.remove()
    document.removeEventListener('pointerup', releaseRipple)
    document.removeEventListener('pointercancel', releaseRipple)
    document.removeEventListener('pointercancel', cancelRipple)
  }

  incrementRippleCount(el)

  if (computedStyles.position === 'static') {
    if (el.style.position) {
      originalPositionValue = el.style.position
    }
    el.style.position = 'relative'
  }

  rippleContainer.appendChild(rippleEl)
  el.appendChild(rippleContainer)

  document.addEventListener('pointerup', releaseRipple)
  document.addEventListener('pointercancel', releaseRipple)

  token = setTimeout(() => {
    document.removeEventListener('pointercancel', cancelRipple)

    requestAnimationFrame(() => {
      rippleEl.style.transform = `translate(-50%,-50%) scale(1)`
      rippleEl.style.opacity = `${options.finalOpacity}`

      setTimeout(() => releaseRipple(), options.duration)
    })
  }, options.delay)
  document.addEventListener('pointercancel', cancelRipple)
}
